package org.uc3m.pfc.command;


import java.util.List;

import org.uc3m.pfc.data.Action;
import org.uc3m.pfc.data.Device;
import org.uc3m.pfc.device.DeviceManager;
import org.uc3m.pfc.device.IDeviceManager;
import org.uc3m.pfc.lifecycle.LifeCycle;
import org.uc3m.pfc.lifecycle.State;
import static org.uc3m.pfc.lifecycle.State.stopped;
import static org.uc3m.pfc.lifecycle.State.processing;
import static org.uc3m.pfc.lifecycle.State.detecting;
import org.uc3m.pfc.marker.manager.IMarkerManager;
import org.uc3m.pfc.marker.manager.MarkerManager;
import org.uc3m.pfc.ui.ActionSelector;

/**
 * 
 * @author esteban
 *
 */
public final class CommandManager extends LifeCycle implements ICommandManager {

	// Class fields *******************************************************
	
	/** Static instance . */
	private static ICommandManager instance;
	
	/** Device manager instance. */
	private IDeviceManager deviceManager;

	/** Marker manager instance. */
	private IMarkerManager markerManager;
	
	/** Modal handler instance. */
	private ActionSelector actionSelector;
	
	
    // Constructor *******************************************************	
	
	/**
	 * Private default constructor.
	 */
	private CommandManager() {

		this.deviceManager = DeviceManager.getInstance();
		this.actionSelector = ActionSelector.getSelector();
		
		this.setState(stopped);
	}
	
	/**
	 * Get the static instance.
	 * 
	 * @return instance
	 */
	public static ICommandManager getInstance() {
		
		if (instance == null) {
			instance = new CommandManager();
		}
		
		return instance;
	}

	
    // ICommandManager methods *********************************************
	
	@Override
	public void executeCommand(final int id) {

		this.setState(processing);
		
		final Runnable commandStart = new Runnable() {
			public void run() {
				
				execute(id);
			}
		};

		Thread t = new Thread(commandStart);
		t.start();
		
	}

	@Override
	public void setMarkerManager(final IMarkerManager pmarkerManager) {
		this.markerManager = pmarkerManager;
		
	}

	
    // LifeCycle methods ***************************************************

	@Override
	public void setState(final State pstate) {
		
		State previousState = this.getState();
		super.setState(pstate);
		
		// back to detecting
		if ((previousState == processing) && (this.getState() == stopped)) {
			
			((MarkerManager) markerManager).setState(detecting);
		}
	}

	
    // Private methods ***************************************************
	
	/**
	 * Executes the action for the detected id.
	 * 
	 * @param id current identifier
	 */
	private void execute(final int id) {

		Device device = deviceManager.getDevice(id);
	
		final List<Action> actions = device.getActions();

		String actionString = actionSelector.selectAction(
				device.getName(), actions);
		
		String message = "";
		
		if (actionString != null) {
		
			Action action = null;
			for (Action actionAux : actions) {
				
				if (actionAux.getName().equalsIgnoreCase(actionString)) {
					action = actionAux;
					break;
				}
			}

			message = deviceManager.executeFunction(device, action);
			
		} else {
			
			message = "Comando no reconocido";
		}
		
		actionSelector.showMessage(message);
		
		this.setState(stopped);
	}

	
}
